;; core/memoize.scm - (c) rohan drape, 2000-2005

;; Memoize the stated argument function `f'.

(define (memoize-zero f)
  (let ((already-run #f) (result #f))
    (lambda ()
      (if (not already-run)
	  (begin 
	    (set! result (f))
	    (set! already-run #t)))
      result)))

(define (memoize-one f)
  (let ((table (make-table)))
    (lambda (argument)
      (let ((record (table-get* table argument)))
	(or record
	    (let ((result (f argument)))
	      (table-put! table argument result)
	      result))))))

(define (memoize-two f)
  (let ((table (make-table)))
    (lambda (a b)
      (let ((record (table-get* table (cons a b))))
	(or record
	    (let ((result (f a b)))
	      (table-put! table (cons a b) result)
	      result))))))

(define (memoize-variable f)
  (let ((table (make-table)))
    (lambda arguments
      (let ((record (table-get* table arguments)))
	(or record
	    (let ((result (apply f arguments)))
	      (table-put! table arguments result)
	      result))))))

;; Aliases

(define memoize0 memoize-zero)
(define memoize1 memoize-one)
(define memoize  memoize-one)
(define memoize2 memoize-two)
(define memoizeN memoize-variable)
